<?
define('REQUEST_ACTION_PARAM', 'a');	// set ?a=xxx querystring for action

// framework master include file
define('DIR_ROOT',realpath(dirname(__file__).'/..').'/');	// full path to the root
define('DIR_FRAMEWORK',dirname(__file__).'/');	// full path to the framework folder

// figure out the URL_BASE_HREF
// <base href='{$smarty.const.URL_BASE_HREF}'>
$p1 = explode("/", $_SERVER['REQUEST_URI']);
$p2 = explode("/", realpath(dirname(__file__).'/..'));
while($p1 && $p1[count($p1)-1]!=$p2[count($p2)-1]) array_pop($p1);
define('URL_BASE_HREF',($_SERVER['HTTPS']?'https':'http').'://'.$_SERVER['HTTP_HOST'].implode("/",$p1).'/');	

// load configuration
require_once(DIR_ROOT."/config.inc");

// force HTTPS if not cli-mode
if (!(php_sapi_name()=='cli' && empty($_SERVER['REMOTE_ADDR']))) // skip check if running from CLI
{
	if ($config['force_https'] && !isset($_SERVER['HTTPS'])) {
		header("Location: https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
		exit;
	}

	ob_start('ob_gzhandler');
	header('Content-Type: text/html; charset='._config('charset','utf-8'));
}

session_start();
$sid = session_id();

require_once(DIR_FRAMEWORK."smarty/Smarty.class.php");
@include_once("language/"._config('language','en').".php");

function __autoload($class_name) {
    require_once DIR_FRAMEWORK . 'class.'.$class_name . '.php';
}

function _config($cfg,$default=false)
{
	global $config;
	return isset($config[$cfg])?$config[$cfg]:$default;
}

function _lang($msg)
{
	global $LANG;
	return isset($LANG[$msg])?$LANG[$msg]:$msg;
}

// module base class
class Module
{
	var $action = '_default';
	const REQUIRE_LOGIN = 0x01;

	// constructor
	function __construct($init_flags=0,$modulename='')
	{
	    global $config; $this->config = &$config;
	    
		if (isset($_REQUEST[REQUEST_ACTION_PARAM]) && $_REQUEST[REQUEST_ACTION_PARAM]!='') $this->action = $_REQUEST[REQUEST_ACTION_PARAM];

		// get user session
		$this->login = $this->get_login($init_flags & Module::REQUIRE_LOGIN);
		
		
		$this->tpl = new Template;
		$this->tpl->assignByRef('this', $this);

		// copy country
		global $_countries;
		$this->_countries = &$_countries;

		// hook up the Mongo database using the PHP Mongo class
		// to install, run sudo pecl install mongo
		$this->mongo = new Mongo();
		$this->db = $this->mongo->selectDB(_config('db'));
		if (!$this->db) die("<h1>Invalid database name</h1>Please specify database in \$config['db']='database';");
		
		// call init if ready
		if (method_exists($this,'init')) $this->init();

		if (!method_exists($this,$this->action))
		{
			print "<h1>"._lang('Unhandled Request')."</h1>";
			print get_class($this) . "::{$this->action} > ";
			print_r($_REQUEST);
			exit;
		}

		// call our own function
		$action = $this->action;
		$this->$action();
	}
	
	function display($tpl)
	{
	    $this->tpl->display($this->tpl->template_dir.'/'.$tpl);
	}

	function fetch($tpl)
	{
	    return $this->tpl->fetch($this->tpl->template_dir.'/'.$tpl);
	}
		
	// sql helper
	function query($sql, $die_on_error = true)
	{
		$ret = $this->db->query($sql);
		if (!$ret && $die_on_error)
		{
		    print "<h1>SQL Error</h1>";
		    print "<b>Query:</b><br />$sql<br /><br />";
		    print "<b>Error:</b><br />";
			print(array_pop($this->db->errorInfo()));
			exit;
		}
		return $ret;
	}

	// return affected rows
	function exec($sql, $die_on_error = true)
	{
		$ret = $this->db->exec($sql);
		if ($ret===false && $die_on_error) die(array_pop($this->db->errorInfo()));
		return $ret;
	}

	function page_not_found()
	{
		if (file_exists(DIR_ROOT.'tpl/page_not_found.tpl')) {
			$this->tpl->config_dir = $this->tpl->template_dir = DIR_ROOT.'tpl/';
			$this->tpl->display(DIR_ROOT.'tpl/page_not_found.tpl');
		}
		else
		{
			print "<h1>"._lang("Page Not Found")."</h1>";
	    	print "<p><big>"._lang("You may have entered an invalid URL or the page no longer exists.")."</big></p>";
	    }
		exit;
	}

	function error($reason)
	{
		if (file_exists(DIR_ROOT.'tpl/error.tpl')) {
			$this->tpl->config_dir = $this->tpl->template_dir = DIR_ROOT.'tpl/';
			$this->tpl->assign("reason",$reason);
			$this->tpl->display(DIR_ROOT.'tpl	/error.tpl');
		}
		else
		{
			print "<h1>"._lang("Page Error")."</h1>";
		    print "<p><big>".htmlspecialchars($reason)."</big></p>";
	    }
		exit;
	}

	function redir($url, $use_header=true)
	{
		if ($use_header)
			header("Location: $url");
	    else
	    	print "<p class=large>"._lang('Redirecting you to')."<br /><a href=\"$url\">$url</a></p><meta http-equiv=\"refresh\" content=\"5;URL=$url\">";
		exit;
	}

	function get_login($login_required=false)
	{
		// yes, already login
		if (isset($_SESSION['login']))
		{
			return $_SESSION['login'];
		}
		elseif ($login_required && $this->action!='login' && $this->action!='logout')
		{
			// redirect to login
			header("Location: "._config('login_url', URL_BASE_HREF.'index.php?a=login').'&redir='.urlencode($_SERVER['REQUEST_URI']));
			exit;
		}
		return false;
	}

	// store the login info to session
	function set_login($user)
	{
		$_SESSION['login'] = $user;
		$this->login = $user;
	}
	
	// clear login info
	function unset_login()
	{
		unset($_SESSION['login']);
		unset($this->login);
	}
	
	// very basic sendmail, if to is a array then it will send to each
	function sendmail($to,$subject,$message,$from='',$attachments='',$cc='',$bcc='')
 	{
 	    $mail_outsider = false;

		if (!$mailto && !$cc && !$bcc) return true; // no mail
		
		if ($from=='') $from = _config('mailsender');
		elseif (!strstr($from,"@")) $from = $from."@"._config('maildomain');

		$mail = new PHPMailerLite();
		$mail->SetFrom($from);

		// send to
		if (!is_array($to)) $to = preg_split('/[,\n\r]+/',trim($to));
		foreach($to as $e)
		{
		    if ($e=='') continue;
		    // add @domain.com to those without domain
		    if (!strstr($e,"@"))
				$e = $e."@"._config('maildomain');
			else
			    $mail_outsider = true; // dont send footer if mail contain outsider!
			$mail->AddAddress($e);
		}
		
		// send cc
		if ($cc)
		{
			if (!is_array($cc)) $cc = preg_split('/[,\n\r]+/',trim($cc));
			foreach($cc as $e)
			{
			    if ($e=='') continue;
			    // add @domain.com to those without domain
			    if (!strstr($e,"@"))
					$e = $e."@"._config('maildomain');
				else
				    $mail_outsider = true; // dont send footer if mail contain outsider!
				$mail->AddCC($e);
			}
		}
		
		// send bcc
		if ($bcc)
		{
			if (!is_array($bcc)) $bcc = preg_split('/[,\n\r]+/',trim($bcc));
			foreach($bcc as $e)
			{
			    if ($e=='') continue;
			    // add @domain.com to those without domain
			    if (!strstr($e,"@"))
					$e = $e."@"._config('maildomain');
				else
				    $mail_outsider = true; // dont send footer if mail contain outsider!
				$mail->AddBCC($e);
			}
		}
		
		$mail->Subject = $subject;

        if (preg_match('/<html>/',$message))
        {
		    $mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
			$mail->MsgHTML($message);
			if (!$mail_outsider) $message .= nl2br(_config('mailfooter'));
		}
		else
		{
		    $mail->IsHTML(false);
			$mail->Body = $message;
    		if (!$mail_outsider) $message .= _config('mailfooter');
		}

		if ($attachments!='')
		{			
		    // attach many file
		    foreach($attachments as $f=>$n)
		    {
		        $mail->AddAttachment($f,$n);
			}
		}
	}		

}


// smarty class for Modules' template
class Template extends Smarty {

	function __construct()
	{
		parent::__construct();
		// if we are not at root directory, then use the template in the same folder as php
		if (getcwd()==realpath(DIR_ROOT)) {
			$this->template_dir = $this->config_dir = DIR_ROOT.'tpl';
		}
		else
		{
			$this->template_dir = $this->config_dir = getcwd();
		}
		$this->compile_dir       = DIR_ROOT.'.c';
		
		// create directory if not found
		if (!is_dir($this->compile_dir))
		{
		    mkdir($this->compile_dir,0777);
		}
	}
}


?>
